#pragma once

#include "noncopyable.h"

#include <string>
#include <cstring>

//宏函数，在使用时不需要自己再去创建获取对象、设置等级等
// LOG_INFO("xxx%s %d",arg1,arg2)
#define LOG_INFO(logmsgFormat, ...)                              \
    do                                                           \
    {                                                            \
        Logger &logger = Logger::getInstance();                  \
        logger.setLogLevel(INFO);                                \
        char buf[1024];                                          \
        snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \
        logger.log(buf);                                         \
    } while (0)

#define LOG_ERROR(logmsgFormat, ...)                             \
    do                                                           \
    {                                                            \
        Logger &logger = Logger::getInstance();                  \
        logger.setLogLevel(ERROR);                               \
        char buf[1024];                                          \
        snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \
        logger.log(buf);                                         \
    } while (0)

#define LOG_FATAL(logmsgFormat, ...)                             \
    do                                                           \
    {                                                            \
        Logger &logger = Logger::getInstance();                  \
        logger.setLogLevel(FATAL);                               \
        char buf[1024];                                          \
        snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \
        logger.log(buf);                                         \
        exit(-1);                                                \
    } while (0)

//条件编译，需要调试时，定义宏才输出调试信息，否则LOG_DEBUG函数什么也不做
#ifdef USEDEBUG    
#define LOG_DEBUG(logmsgFormat, ...)                             \
    do                                                           \
    {                                                            \
        Logger &logger = Logger::getInstance();                  \
        logger.setLogLevel(DEBUG);                               \
        char buf[1024];                                          \
        snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \
        logger.log(buf);                                         \
    } while (0)
#else
#define LOG_DEBUG(logmsgFormat, ...)
#endif

// 日志等级
enum LogLevel
{
    INFO = 1,
    ERROR,
    FATAL,
    DEBUG
};

// 单例日志类
class Logger : noncopyable
{
public:
    // 获取单例对象接口
    static Logger &getInstance();
    // 设置日志等级
    void setLogLevel(int logLevel);
    // 写日志
    void log(std::string);

private:
    int logLevel_;

    Logger() {}
    static Logger logger;
};

//单例的定义应放在源文件中
// Logger Logger::logger;